package com.aivin.lint_lib_java.detector;

import com.aivin.lint_lib_java.JavaLog;
import com.android.tools.lint.detector.api.Category;
import com.android.tools.lint.client.api.UElementHandler;
import com.android.tools.lint.detector.api.Detector;
import com.android.tools.lint.detector.api.Implementation;
import com.android.tools.lint.detector.api.Issue;
import com.android.tools.lint.detector.api.JavaContext;
import com.android.tools.lint.detector.api.Scope;
import com.android.tools.lint.detector.api.Severity;

import org.jetbrains.annotations.NotNull;
import org.jetbrains.uast.UClass;
import org.jetbrains.uast.UElement;
import org.jetbrains.uast.UMethod;
import org.jetbrains.uast.visitor.AbstractUastVisitor;
import java.util.Collections;
import java.util.EnumSet;
import java.util.List;

public class AVNamingConventionDetector extends Detector implements Detector.UastScanner {
    //定义命名规范规则
    public static final Issue ISSUE = Issue.create("Aivin_NameIssue",
            "命名不规范",
            "使用驼峰命名法，方法命名开头小写",
            Category.CORRECTNESS,
            5,
            Severity.ERROR,
            new Implementation(AVNamingConventionDetector.class,
                    EnumSet.of(Scope.JAVA_FILE)));

    //返回我们所有感兴趣的类，即返回的类都被会检查
    @Override
    public List<Class<? extends UElement>> getApplicableUastTypes() {
        return Collections. singletonList(UClass.class);
    }

    //重写该方法，创建自己的处理器
    @Override
    public UElementHandler createUastHandler(@NotNull final JavaContext context) {
        return new UElementHandler() {
            @Override
            public void visitClass(@NotNull UClass node) {
                node.accept(new NamingConventionVisitor(context, node));
            }
        };
    }
    //定义一个继承自AbstractUastVisitor的访问器，用来处理感兴趣的问题
    public  class NamingConventionVisitor extends AbstractUastVisitor {
        JavaContext context;
        UClass uClass;

        public NamingConventionVisitor(JavaContext context, UClass uClass) {
            this.context = context;
            this.uClass = uClass;
        }

        @Override
        public boolean visitClass(@org.jetbrains.annotations.NotNull UClass node) {
            //获取当前类名
            String name = node.getName();
            if(name==null){
                return super.visitClass(node);
            }


            char beginChar = node.getName().charAt(0);
            boolean isUp = Character.isUpperCase( beginChar) ;

            if(!isUp){
                context.report(ISSUE,
                        context.getNameLocation(node),
                        "类名必须大写开头  " + node.getName() );
                JavaLog.showLog("检测到类名不规范=="+ node.getName());
                //返回true表示触碰规则，lint提示该问题；false则不触碰
                return true;
            }
            return super.visitClass(node);
        }

        @Override
        public boolean visitMethod(@NotNull UMethod node) {

            //当前方法是构造方法
            if(node.isConstructor()){
                return super.visitMethod(node);
            }

            char beginChar = node.getName().charAt(0);
            boolean isLow = Character.isLowerCase( beginChar) ;

            //当前方法首字母是大写字母，则报Issue
            if (  !isLow ) {
                context.report(ISSUE, context.getLocation(node),
                        "方法名必须以小写开头 " + node.getName());
                JavaLog.showLog("检测到方法名不规范=="+ node.getName());
                return true;
            }

            return super.visitMethod(node);
        }

    }
}
